import json
import os
import urllib
import urlparse
import webapp2
import logging
import httplib2
import time

from google.appengine.api import app_identity
from google.appengine.api import urlfetch
from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import ndb
from google.appengine.ext.webapp import template

from apiclient.discovery import build
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from oauth2client.appengine import AppAssertionCredentials

# BigQuery API Settings
SCOPE = 'https://www.googleapis.com/auth/bigquery'
PROJECT_NUMBER = app_identity.get_application_id()

# Create a new API service for interacting with BigQuery
credentials = AppAssertionCredentials(scope=SCOPE)
http = credentials.authorize(httplib2.Http())
bigquery_service = build('bigquery', 'v2', http=http)


def runAsyncQuery (service, projectId, queryString):
  try:
    jobCollection = service.jobs()
    jobData = {
      'configuration': {
        'query': {
          'query': queryString,
        }
      }
    }

    insertResponse = jobCollection.insert(projectId=projectId,
                                         body=jobData).execute()

    # Get query results. Results will be available for about 24 hours.
    currentRow = 0
    queryReply = jobCollection.getQueryResults(
                      projectId=projectId,
                      jobId=insertResponse['jobReference']['jobId'],
                      startIndex=currentRow,timeoutMs=100000).execute()

    return queryReply

  except Exception as err:
    print 'Undefined error: {}'.format(err)
    return None

class LangCorrHandler(webapp2.RequestHandler):
  def post(self):

    lang1 = self.request.get('lang1')
    lang2 = self.request.get('lang2')

    queryString = """
select actor, repository_language, count(repository_language) as pushes
from [githubarchive:github.timeline]
where type='PushEvent'
    and repository_language == '""" + lang1 + """' or repository_language == '""" + lang2 + """'
    and PARSE_UTC_USEC(created_at) >= PARSE_UTC_USEC('2012-01-01 00:00:00')
    and PARSE_UTC_USEC(created_at) < PARSE_UTC_USEC('2013-01-01 00:00:00')
group by actor, repository_language
order by pushes desc
LIMIT 100"""
    data = runAsyncQuery(bigquery_service, PROJECT_NUMBER, queryString)
    
    if data == None:
      data = runAsyncQuery(bigquery_service, PROJECT_NUMBER, queryString)

    result = {
      'data': data
    }

    self.response.headers['Access-Control-Allow-Origin'] = '*'
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(json.dumps(result))

  def options(self):
    self.response.headers['Access-Control-Allow-Origin'] = '*'
    self.response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
    self.response.headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE'

class ForksHandler(webapp2.RequestHandler):
  def post(self):

    s = self.request.get('start-time')
    e = self.request.get('end-time')

    queryString = """
SELECT repository_url, MAX(repository_forks) as total_number_of_forks
FROM [githubarchive:github.timeline]
WHERE
    PARSE_UTC_USEC(created_at) >= PARSE_UTC_USEC('""" + s + """ 00:00:00') AND
    PARSE_UTC_USEC(created_at) < PARSE_UTC_USEC('""" + e + """ 00:00:00')
GROUP EACH BY repository_url
ORDER BY total_number_of_forks DESC
LIMIT 10"""
    data = runAsyncQuery(bigquery_service, PROJECT_NUMBER, queryString)

    result = {
      'data': data
    }

    self.response.headers['Access-Control-Allow-Origin'] = '*'
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(json.dumps(result))

  def options(self):
    self.response.headers['Access-Control-Allow-Origin'] = '*'
    self.response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
    self.response.headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE'

class HappyLangsHandler(webapp2.RequestHandler):
  def post(self):

    token = self.request.get('token')

    queryString = """
SELECT repository_language, COUNT(*) AS cntlang
FROM [githubarchive:github.timeline]
WHERE repository_language != ''
AND payload_commit_msg != ''
AND PARSE_UTC_USEC(created_at) > PARSE_UTC_USEC('2000-03-09 00:00:00')
AND REGEXP_MATCH(payload_commit_msg, r'(?i)\\b(""" + token + """)\\b')
GROUP BY repository_language
ORDER BY cntlang DESC"""
    data = runAsyncQuery(bigquery_service, PROJECT_NUMBER, queryString)

    result = {
      'data': data
    }

    self.response.headers['Access-Control-Allow-Origin'] = '*'
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(json.dumps(result))

  def options(self):
    self.response.headers['Access-Control-Allow-Origin'] = '*'
    self.response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
    self.response.headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE'

class BqHandler(webapp2.RequestHandler):

  def get(self):
      # Return template with context variables
      template_values = {}
      path = os.path.join(os.path.dirname(__file__), 'bq.html')
      self.response.out.write(template.render(path, template_values))

application = webapp2.WSGIApplication([
  ('/langcorr', LangCorrHandler),
  ('/forks', ForksHandler),
  ('/happylangs', HappyLangsHandler),
  ('/bq', BqHandler)
], debug=True)